package satirGame;

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.event.ActionEvent;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;



/**
 * @author dare
 * 
 */
public class Stage extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3165470712061013756L;
	public static JFrame gameFrame = new JFrame("HelloWorldSwing1");
	public static Map gameMap;// = new
								// Map(getMapNodeNum(),getMapNodeWidth(),getMapNodeHeight());

	public static int remainRound;
	static int numOfPlayer;
	private static int curPlayer = 0;
	private int minPlayer = 3;
	private int maxPlayer = 6;
	private static int mapNodeNum = 60;
	private static int mapNodeWidth = 10;
	private static int mapNodeHeight = 6;
	static Container gameContainer;
	public static ArrayList<Player> playerArray;

	private static int[] remainRole = { -1, -1, -1, -1, -1, -1 };
	static Event[] eventArray = new Event[3];
	public static Scanner uInput = new Scanner(System.in);
	private static JLabel remainRoundNUMLabel;
	public static void main(String[] args) throws IOException {
		gameFrame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		gameFrame.setTitle("Satir Game");
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		int screenHeight = screenSize.height;
		int screenWidth = screenSize.width;
		gameFrame.setSize(screenWidth, screenHeight);
		gameFrame.setLocation(screenWidth / 4, 0);
		gameFrame.setVisible(true);
		gameContainer = gameFrame.getContentPane();
		gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gameContainer.setLayout(new GridBagLayout());
		Stage.drawScene();
	}

	private static void drawScene() throws IOException {
		rolePlaySetupScene();
		moveCheseScene();

	}

	private static void rolePlaySetupScene() throws IOException {

		Object[] options = { 3, 4, 5, 6 };
		int playerNum = JOptionPane.showOptionDialog(gameFrame,
				"How many players for this game:", "Number of Player",
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, 
				options, // the titles of buttons
				options[0]) + 3; // default button title

		setNumPlayer(playerNum);

		remainRound=playerNum*3;
		GridBagConstraints gridBagLayout = new GridBagConstraints();
		gridBagLayout.gridx = 0;
		gridBagLayout.gridy = 0;
		gridBagLayout.gridwidth =1;
		gridBagLayout.gridheight = 1;
		gridBagLayout.weightx = 0;
		gridBagLayout.weighty = 0;
		gridBagLayout.fill = GridBagConstraints.BOTH;
		gridBagLayout.anchor = GridBagConstraints.CENTER;
		JLabel remainRoundLable=new JLabel("Remain Round:");
		gameFrame.add(remainRoundLable,gridBagLayout);
		
		remainRoundNUMLabel=new JLabel();
		
		remainRoundUpdate();
		gridBagLayout = new GridBagConstraints();
		gridBagLayout.gridx = 1;
		gridBagLayout.gridy = 0;
		gridBagLayout.gridwidth =1;
		gridBagLayout.gridheight = 1;
		gridBagLayout.weightx = 0;
		gridBagLayout.weighty = 0;
		gridBagLayout.fill = GridBagConstraints.BOTH;
		gridBagLayout.anchor = GridBagConstraints.CENTER;
		gameFrame.add(remainRoundNUMLabel,gridBagLayout);
		
		gameMap = new Map(getMapNodeNum(), getMapNodeWidth(),
				getMapNodeHeight());
		gridBagLayout = new GridBagConstraints();
		gridBagLayout.gridx = 0;
		gridBagLayout.gridy = 1;
		gridBagLayout.gridwidth = playerNum - 1;
		gridBagLayout.gridheight = 1;
		gridBagLayout.weightx = 0;
		gridBagLayout.weighty = 0;
		gridBagLayout.fill = GridBagConstraints.BOTH;
		gridBagLayout.anchor = GridBagConstraints.CENTER;
		gameFrame.add(gameMap, gridBagLayout);
		gameMap.revalidate();
		/*
		 * return;
		 */
		// gameContainer.add(playerArray.get(0).PlayerInfoPanel(40,40));
	}

	private static void remainRoundUpdate() {
		remainRoundNUMLabel.setText(String.valueOf(remainRound));
		remainRoundNUMLabel.revalidate();
	}

	private static void moveCheseScene() {
		for (int i = 0; i < getNumPlayer(); i++) {
			GridBagConstraints gridBagLayout = new GridBagConstraints();
			gridBagLayout.gridx = i;
			gridBagLayout.gridy = 2;
			gridBagLayout.gridwidth = 1;
			gridBagLayout.gridheight = 0;
			gridBagLayout.weightx = 0;
			gridBagLayout.weighty = 0;
			gridBagLayout.fill = GridBagConstraints.NONE;
			gridBagLayout.anchor = GridBagConstraints.CENTER;
			gameFrame.add(playerArray.get(i).PlayerInfoPanel(), gridBagLayout);

		}
		setPlayerBG();
				gameMap.drawMap();
				
		ActionListener action = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				MapNode obj = (MapNode) e.getSource();
				System.out.println("Activated: " + obj.getIndex());
				if(remainRound>0){
				if (gameMap.isNodeCanGo(obj.getIndex())) {
					gameMap.removeCurPlayerOnNode(playerArray.get(curPlayer).getCurPos());
					playerArray.get(curPlayer).setCurPos(obj.getIndex());
					gameMap.setCurPlayerOnNode(playerArray.get(curPlayer).getCurPos(),playerArray.get(curPlayer).getRealRole());
					gameMap.resetMap();
					if (gameMap.isNodeContainEvent(obj.getIndex())) {
						try {
							int randomNO = (int) (Math.random() * 1000)%3;
							eventArray[randomNO].loadQuestion(gameFrame);
							playerArray.get(curPlayer).addScore(eventArray[randomNO].getScore());
							System.out.println("player score: " + playerArray.get(curPlayer).getScore());
						} catch (FileNotFoundException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					remainRound--;
					remainRoundUpdate();
					setCurPlayer();
				}
				} else
					try {
						stateCheckScene();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
			}
		};
		for (int i = 0; i < mapNodeHeight; i++) {
			for (int j = 0; j < mapNodeWidth; j++) {
				gameMap.nodesInstance[i][j].addActionListener(action);
			}
		}
		gameMap.setCurPlayerOnNode(playerArray.get(curPlayer).getCurPos(),playerArray.get(curPlayer).getRealRole());
	}


	private static void stateCheckScene() throws IOException {
		// clean memory
		System.gc();
		String winnerNameString=playerArray.get(0).getName();
		int maxScore=playerArray.get(0).getScore();
		for(int i=0;i<numOfPlayer;i++){
			if(playerArray.get(i).getScore()>maxScore){
				winnerNameString=playerArray.get(i).getName();
				maxScore=playerArray.get(i).getScore();
			}
		}
		Object[] options = { "Restart Game", "Exit Program" };
		int choice = JOptionPane.showOptionDialog(gameFrame,
				"Winner is : "+winnerNameString +"\nPlease Choose an action", "End Game",
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, 
				options, // the titles of buttons
				options[0]); // default button title
		if (choice==0) {
			remainRole = new int[] { -1, -1, -1, -1, -1, -1 };
			gameFrame.remove(gameMap);
			gameFrame.remove(gameContainer);
			for (int i = 0; i < getNumPlayer(); i++) {
				gameFrame.remove(playerArray.get(i).p);
			}
			gameFrame.remove(remainRoundNUMLabel);
			gameFrame.repaint();
			drawScene();
		}else
			System.exit(0);
	}

	public static int getNumPlayer() {
		return numOfPlayer;
	}

	public static void setNumPlayer(int n) throws FileNotFoundException {
		numOfPlayer = n;
		// setup players object
		playerArray = new ArrayList<Player>(getNumPlayer());
		for (int i = 0; i < getNumPlayer(); i++) {
			
			Player p = new Player(remainRole, gameFrame, (i + 1));
			while (isPlayerNameRepeat(p.getName())) {
				JOptionPane.showMessageDialog(gameFrame, "Name Repeated");
				p = new Player(remainRole, gameFrame, (i + 1));
			}
			remainRole[p.getRealRole()] = p.getRealRole();
			playerArray.add(p);
		}
		// setup 3 type of event object

		eventArray[0] = new SayActEvent(0);
		eventArray[1] = new SayActEvent(1);
		eventArray[2] = new SituationEvent(getNumPlayer());
		// eventArray[2].loadQuestion(gameFrame);
	}

	public static int getCurPlayer() {
		return curPlayer;
	}

	public static int getPrevPlayer() {
		if (getCurPlayer() == 0) {
			return numOfPlayer - 1;
		} else
			return (getCurPlayer() - 1);
	}

	public static void setCurPlayer() {
		curPlayer = (curPlayer + 1) % numOfPlayer;
		gameMap.setCurPlayerOnNode(playerArray.get(curPlayer).getCurPos(),playerArray.get(curPlayer).getRealRole());
		gameMap.drawMap();
		setPlayerBG();
		
	}

	public void resetCurPlayer(int c) {
		curPlayer = c;
	}

	public static void setPlayerBG() {
		playerArray.get(getPrevPlayer()).setInfoPanelAsPrev();
		playerArray.get(getCurPlayer()).setInfoPanelAsCurrent();
	}

	public static boolean isPlayerNameRepeat(String name) {
		boolean repeated = false;
		for (int i = 0; i < playerArray.size(); i++) {
			if (playerArray.get(i).getName().equals(name)) {
				repeated = true;
			}
		}
		return repeated;
	}

	public void setRemainRound(int roundnum) {
		remainRound = roundnum;
	}

	public void minusRemainRound() {
		remainRound--;
	}

	public int getRemainRound() {
		return remainRound;
	}

	public void setMapNodeNum(int mNodeNum) {
		Stage.mapNodeNum = mNodeNum;
	}

	public static int getMapNodeNum() {
		return mapNodeNum;
	}

	public void setMapNodeWidth(int mapNodeWidth) {
		Stage.mapNodeWidth = mapNodeWidth;
	}

	public static int getMapNodeWidth() {
		return mapNodeWidth;
	}

	public void setMapNodeHeight(int mapNodeHeight) {
		Stage.mapNodeHeight = mapNodeHeight;
	}

	public static int getMapNodeHeight() {
		return mapNodeHeight;
	}

	public void setMinPlayer(int min) {
		this.minPlayer = min;
	}

	public int getMinPlayer() {
		return minPlayer;
	}

	public void setMaxPlayer(int max) {
		this.maxPlayer = max;
	}

	public int getMaxPlayer() {
		return maxPlayer;
	}
}

/*----------------Version detail----------------------------

 Modified time: 02:37_05/03/2012

 Editor: Lam Kit Yung

 Content: 

 Add variables:

 Add new functions



 /*----------------Version detail----------------------------

 Modified time: 02:37_13/03/2012

 Editor: Lam Kit Yung

 Content: 

 Add variables:

 Add new functions


 -----------------------------------------------------------
 ----------------Version detail----------------------------

 Modified time: 16:37_13/03/2012

 Editor: Lam Kit Yung

 Content: 

 Rename variables:
 timeRemain -> remainRound;
 Add new functions
 public void setRound(int Roundnum);
 public void minusRound();
 public int getRound();

 Change function:
 moveChessSence();

 change static of all function and 
 -----------------------------------------------------------
 ----------------Version detail----------------------------

 Modified time: 02:00_09/04/2012

 Editor: Lam Kit Yung

 Content: 

 Change function:
 setNumPlayer();

 Bug Found:
 isPlayerNameRepeat();
 -----------------------------------------------------------
 ----------------Version detail----------------------------

 Modified time: 17:00_09/04/2012

 Editor: Lam Kit Yung

 Content: 

 Change function:

 Bug Fixed:
 isPlayerNameRepeat();
 -----------------------------------------------------------
 */

